import React,{ Component } from 'react';

//一// 父组件向子组件通信 C => D
// 方法：props方法
// 子组件
const ListItem1 = ({ value }) => (
    <li>
        <span>{ value }</span>
    </li>
);

// 父组件
const List1 = ({ List,Title }) => (
    <ul>
        {
            this.props.list.map((entry,index) => (
                <ListItem1 key={ index } value={ entry.text }/>
            ))
        }
    </ul>
);

//二// 父组件向子组件跨级通信 A => D
// 方法：context方法
// 子组件
class ListItem2 extends Component {
    render() {
        const { value } = this.props;
        return (
            <li style={{
                    backgroundColor: this.context.color
                }}>
                <span>{ value }</span>
            </li>
        )
    }
}
// 父组件
class List2 extends Component {
    getChildContext() {
        return {
            color: `red`
        }
    }
    render() {
        const { list } = this.props;
        return (
            <ul>
                {list.map((entry,index) 
                    => <ListItem2 key={ index } value={ entry.text }></ListItem2>)}
            </ul>
        )
    }
}

//三// 子组件向父组件通信 D => C
// 方法1：事件回调
// 子组件
class ListItem3 extends Component {
    render() {
        return (
            <li>
                <input typr="checkbox" onChange={ this.props.onChange }/>
            </li>
        )
    }
}

// 父组件
class List3 extends Component {
    constructor(props){
        super(props);
    }
    change() {
        console.log("change");
    }
    render(){
        return (
            <ul>
                {list.map((entry,index) => <ListItem3 onChange={ ::this.change }></ListItem3>)}
            </ul>
        )
    }
}

// 方法2：自定义回调
// 子组件
class ListItem4 extends Component {
    change(){
        this.props.callBack("callBack");
    }
    render() {
        return (
            <li>
                <input typr="checkbox" onChange={ ::this.change }/>
            </li>
        )
    }
}

// 父组件
class List4 extends Component {
    constructor(props){
        super(props);
    }
    callBack(a) {
        console.log(a);
    }
    render(){
        return (
            <ul>
                {list.map((entry,index) => <ListItem4 callBack={ ::this.callBack }></ListItem4>)}
            </ul>
        )
    }
}

//四// 无嵌套关系组件通信 E => D
// 方法一：监听者和订阅者观察者模式(Pub/Sub)开发(RXJS)
// 私募的权限管理（因为权限管理模块虽然是组件，但在最外层，有些props过深入，通过简单的props每个组件传递会使得性能下降）
// 增加一个观察者
import { Subject } from "rxjs/Subject";
// 登录流操作
export const oauth = new Subject;
// 登录判断请求如果为401
 if(xhr.status == "401"){
    //退出登录
    oauth.next({
        username: "",
        userShow: "none"
    });
}
// 组件中监听这个观察者，建立订阅者
class List5 extends Component {
    constructor(props){
        super(props);
        oauth.subscribe(() => {
            //TODO:
        });
    }
    componentWillUnmount() {
        // 结束订阅
        oauth.unsubscribe();
    }
    render(){
        return (
            <ul>
                .....
            </ul>
        )
    }
}
// Pub/Sub 观察者模式定义在全局虽然在软件开发大规模使用，并且使用方便，
// 副作用就是逻辑关系的混乱，可能造成不知道哪里触发了订阅者

// 方法二：EventEmitter
// 和RXJS一样都是发布和订阅不再重复演示
